home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / demos / spectex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-21  |  5.6 KB  |  231 lines

  1. /* spectex.c */
  2.  
  3. /*
  4.  * GLUT demonstration of texturing with specular highlights.
  5.  *
  6.  * When drawing a lit, textured surface one usually wants the specular
  7.  * highlight to override the texture colors.  However, OpenGL applies
  8.  * texturing after lighting so the specular highlight is modulated by
  9.  * the texture.
  10.  *
  11.  * The solution here shown here is a two-pass algorithm:
  12.  *  1. Draw the textured surface without specular lighting.
  13.  *  2. Enable blending to add the next pass:
  14.  *  3. Redraw the surface with a matte white material and only the
  15.  *     specular components of light sources enabled.
  16.  *
  17.  * Brian Paul   February 1997
  18.  */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include <GL/glut.h>
  25.  
  26.  
  27. static GLUquadricObj *Quadric;
  28. static GLuint Sphere;
  29. static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
  30. static GLfloat Delta = 1.0;
  31. static GLint Mode = 0;
  32.  
  33. static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};
  34. static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};
  35. static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
  36. static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
  37.  
  38.  
  39.  
  40. static void Idle( void )
  41. {
  42.    LightPos[0] += Delta;
  43.    if (LightPos[0]>15.0)
  44.       Delta = -1.0;
  45.    else if (LightPos[0]<-15.0)
  46.       Delta = 1.0;
  47.  
  48.    glutPostRedisplay();
  49. }
  50.  
  51.  
  52. static void Display( void )
  53. {
  54.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  55.  
  56.    glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  57.  
  58.    glPushMatrix();
  59.    glRotatef(90.0, 1.0, 0.0, 0.0);
  60.  
  61.    if (Mode==0) {
  62.       /* Typical method: diffuse + specular + texture */
  63.       glEnable(GL_TEXTURE_2D);
  64.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  65.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  66.       glCallList(Sphere);
  67.    }
  68.    else if (Mode==1) {
  69.       /* just specular highlight */
  70.       glDisable(GL_TEXTURE_2D);
  71.       glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
  72.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  73.       glCallList(Sphere);
  74.    }
  75.    else if (Mode==2) {
  76.       /* diffuse textured */
  77.       glEnable(GL_TEXTURE_2D);
  78.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  79.       glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
  80.       glCallList(Sphere);
  81.    }
  82.    else if (Mode==3) {
  83.       /* 2-pass: diffuse textured then add specular highlight*/
  84.       glEnable(GL_TEXTURE_2D);
  85.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  86.       glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
  87.       glCallList(Sphere);
  88.       /* specular highlight */
  89.       glDepthFunc(GL_EQUAL);  /* redraw same pixels */
  90.       glDisable(GL_TEXTURE_2D);
  91.       glEnable(GL_BLEND);  /* add */
  92.       glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
  93.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  94.       glCallList(Sphere);
  95.       glDepthFunc(GL_LESS);
  96.       glDisable(GL_BLEND);
  97.    }
  98.  
  99.    glPopMatrix();
  100.  
  101.    glutSwapBuffers();
  102. }
  103.  
  104.  
  105. static void Reshape( int width, int height )
  106. {
  107.    glViewport( 0, 0, width, height );
  108.    glMatrixMode( GL_PROJECTION );
  109.    glLoadIdentity();
  110.    glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
  111.    glMatrixMode( GL_MODELVIEW );
  112.    glLoadIdentity();
  113.    glTranslatef( 0.0, 0.0, -12.0 );
  114. }
  115.  
  116.  
  117. static void Key( unsigned char key, int x, int y )
  118. {
  119.    switch (key) {
  120.       case 27:
  121.          exit(0);
  122.          break;
  123.    }
  124.    glutPostRedisplay();
  125. }
  126.  
  127.  
  128. static void SpecialKey( int key, int x, int y )
  129. {
  130.    switch (key) {
  131.       case GLUT_KEY_UP:
  132.          break;
  133.       case GLUT_KEY_DOWN:
  134.          break;
  135.    }
  136.    glutPostRedisplay();
  137. }
  138.  
  139.  
  140. static void Init( void )
  141. {
  142.    int i, j;
  143.    GLubyte texImage[64][64][3];
  144.  
  145.    glEnable(GL_LIGHTING);
  146.    glEnable(GL_LIGHT0);
  147.    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
  148.    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
  149.  
  150.    glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
  151.    glMaterialfv(GL_FRONT, GL_SPECULAR, White);
  152.    glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
  153.  
  154.    /* Actually, these are set again later */
  155.    glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
  156.    glLightfv(GL_LIGHT0, GL_SPECULAR, White);
  157.  
  158.    Quadric = gluNewQuadric();
  159.    gluQuadricTexture( Quadric, GL_TRUE );
  160.  
  161.    Sphere= glGenLists(1);
  162.    glNewList( Sphere, GL_COMPILE );
  163.    gluSphere( Quadric, 1.0, 24, 24 );
  164.    glEndList();
  165.  
  166.    glEnable(GL_DEPTH_TEST);
  167.    glEnable(GL_CULL_FACE);
  168.  
  169.    for (i=0;i<64;i++) {
  170.       for (j=0;j<64;j++) {
  171.          int k = ((i>>3)&1) ^ ((j>>3)&1);
  172.          texImage[i][j][0] = 255*k;
  173.          texImage[i][j][1] = 255*(1-k);
  174.          texImage[i][j][2] = 0;
  175.       }
  176.    }
  177.  
  178.    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  179.    glTexImage2D( GL_TEXTURE_2D,
  180.                  0,
  181.                  3,
  182.                  64, 64,
  183.                  0,
  184.                  GL_RGB, GL_UNSIGNED_BYTE,
  185.                  texImage );
  186.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  187.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  188.    glEnable(GL_TEXTURE_2D);
  189.  
  190.    glBlendFunc(GL_ONE, GL_ONE);
  191. }
  192.  
  193.  
  194. static void ModeMenu(int entry)
  195. {
  196.    if (entry==99)
  197.       exit(0);
  198.    Mode = entry;
  199. }
  200.  
  201.  
  202. int main( int argc, char *argv[] )
  203. {
  204.  
  205.    glutInit( &argc, argv );
  206.    glutInitWindowPosition( 0, 0 );
  207.    glutInitWindowSize( 300, 300 );
  208.  
  209.    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  210.  
  211.    glutCreateWindow( "spectex" );
  212.  
  213.    Init();
  214.  
  215.    glutReshapeFunc( Reshape );
  216.    glutKeyboardFunc( Key );
  217.    glutSpecialFunc( SpecialKey );
  218.    glutDisplayFunc( Display );
  219.    glutIdleFunc( Idle );
  220.  
  221.    glutCreateMenu( ModeMenu );
  222.    glutAddMenuEntry("1-pass lighting + texturing", 0);
  223.    glutAddMenuEntry("specular lighting", 1);
  224.    glutAddMenuEntry("diffuse lighting + texturing", 2);
  225.    glutAddMenuEntry("2-pass lighting + texturing", 3);
  226.    glutAddMenuEntry("Quit", 99);
  227.    glutAttachMenu(GLUT_RIGHT_BUTTON);
  228.  
  229.    glutMainLoop();
  230. }
  231.